package com.yungu.swift.admin.route.order;

import com.alibaba.dubbo.config.annotation.Reference;
import com.yungu.swift.admin.base.CurrentUser;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.base.model.PageVo;
import com.yungu.swift.base.model.admin.AdminParam;
import com.yungu.swift.base.model.admin.AdminUuidParam;
import com.yungu.swift.constants.CommonConstant;
import com.yungu.swift.constants.MagicConstant;
import com.yungu.swift.constants.OrderConstant;
import com.yungu.swift.order.model.dto.OrderFareDto;
import com.yungu.swift.order.model.param.*;
import com.yungu.swift.order.model.vo.AdminGeneralOrderDetailVo;
import com.yungu.swift.order.model.vo.AdminGeneralOrderVo;
import com.yungu.swift.order.model.vo.OrderEstimateVo;
import com.yungu.swift.order.service.OrderAdminService;
import com.yungu.swift.order.service.OrderAssignService;
import com.yungu.swift.order.service.OrderDetailService;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.utils.DateUtils;
import com.yungu.swift.utils.ParamUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.codehaus.jackson.map.util.BeanUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;

import static com.yungu.swift.admin.consts.AdminErrorEnum.PARAM_ERROR;

/**
 * 订单操作公共接口
 *
 * @author : cuixiuyin
 * @date : 2019/7/15
 */
@Slf4j
@RestController
@RequestMapping("/admin/v1/order/common")
@Api(value = "【订单管理】", tags = "订单操作公共接口")
public class OrderAdmin {

    @Reference
    private OrderAdminService orderAdminService;
    @Reference
    private OrderDetailService orderDetailService;
    @Reference
    private OrderAssignService orderAssignService;
    @Reference
    private OrderFareService orderFareService;

    @RequestMapping(value = "/queryPage", method = RequestMethod.POST)
    @ApiOperation(value = "专车/快车/出租车信息分页查询", httpMethod = "POST")
    public ResponseData<PageVo<AdminGeneralOrderVo>> queryPage(@RequestBody AdminOrderPageParam orderPageParam) {
        if (ParamUtil.isIllegal(orderPageParam.getTypeModule())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        return orderAdminService.queryPageCommon(orderPageParam);
    }

    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    @ApiOperation(value = "专车/快车/出租车/跨城订单详情", httpMethod = "GET")
    public ResponseData<AdminGeneralOrderDetailVo> detail(@RequestParam String uuid, @CurrentUser AdminParam adminParam) {
        if (ParamUtil.isIllegal(uuid)) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        AdminUuidParam adminUuidParam = new AdminUuidParam();
        BeanUtils.copyProperties(adminParam, adminUuidParam);
        adminUuidParam.setUuid(uuid);
        return orderDetailService.getGeneralOrderDetail(adminUuidParam);
    }

    @RequestMapping(value = "/close", method = RequestMethod.POST)
    @ApiOperation(value = "专车/快车/出租车订单关闭", httpMethod = "POST")
    public ResponseData<Boolean> close(@RequestBody AdminAssOrCloseParam assOrCloseParam) {
        if (ParamUtil.isIllegal(assOrCloseParam.getReason(), assOrCloseParam.getOrderUuid(), assOrCloseParam.getBusinessType())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        if (CommonConstant.BUSINESS_TYPE_TAXI == assOrCloseParam.getBusinessType()) {
            return orderAdminService.closeTaxiOrder(assOrCloseParam);
        }
        return orderAdminService.close(assOrCloseParam);
    }

    @RequestMapping(value = "/reassign", method = RequestMethod.POST)
    @ApiOperation(value = "专车/快车/出租车订单改派", httpMethod = "POST")
    public ResponseData<Boolean> ass(@RequestBody AdminAssOrCloseParam assOrCloseParam) {
        if (ParamUtil.isIllegal(assOrCloseParam.getReason(), assOrCloseParam.getOrderUuid(), assOrCloseParam.getBusinessType(),
                assOrCloseParam.getAssMobile())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        if (CommonConstant.BUSINESS_TYPE_TAXI == assOrCloseParam.getBusinessType()) {
            return orderAssignService.reassignTaxiOrder(assOrCloseParam);
        }
        return orderAssignService.reassign(assOrCloseParam);
    }

    @RequestMapping(value = "/abnormalRemark", method = RequestMethod.POST)
    @ApiOperation(value = "专车/快车/出租车/跨城订单添加异常备注", httpMethod = "POST")
    public ResponseData<Boolean> updateAbnormal(@RequestBody AdminOrderAbnormalParam abnormalParam) {
        if (ParamUtil.isIllegal(abnormalParam.getOrderUuid(), abnormalParam.getTypeAbnormal())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        return orderAdminService.abnormalRemark(abnormalParam);
    }

    @RequestMapping(value = "/adjustFare", method = RequestMethod.POST)
    @ApiOperation(value = "后台调整订单金额", httpMethod = "POST")
    public ResponseData<Boolean> adjustFare(@RequestBody AdminOrderAdjustFareParam orderAdjustFareParam) {
        if (ParamUtil.isIllegal(orderAdjustFareParam.getOrderUuid(), orderAdjustFareParam.getPreLatestOrderFare(),
                orderAdjustFareParam.getPreLatestDistance(), orderAdjustFareParam.getNowLatestDistance(),
                orderAdjustFareParam.getNowLatestOrderFare())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        return orderFareService.adjustFare(orderAdjustFareParam);
    }


    @RequestMapping(value = "/fareDetail", method = RequestMethod.GET)
    @ApiOperation(value = "获取订单费用详情", httpMethod = "GET")
    public ResponseData<OrderFareDto> getFareInfo(@RequestParam String orderUuid) {
        return orderFareService.getOrderFareDetail(orderUuid);
    }

    @RequestMapping(value = "/estimateFare", method = RequestMethod.POST)
    @ApiOperation(value = "预估订单费用", httpMethod = "POST")
    public ResponseData<OrderEstimateVo> estimateFare(@RequestBody AdminOrderEstimateParam estimateParam) {
        if (ParamUtil.isIllegal(estimateParam.getOrderUuid(), estimateParam.getDeparTime(),
                estimateParam.getPlanDuration(), estimateParam.getPlanMileage())) {
            return ResponseData.buildErrorResponse(PARAM_ERROR.getCode(), PARAM_ERROR.getMsg());
        }
        ApiOrderUuidParam orderUuidParam = new ApiOrderUuidParam();
        orderUuidParam.setOrderUuid(estimateParam.getOrderUuid());
        return orderFareService.getRealtimeFare(orderUuidParam);
    }


    @RequestMapping(value = "/export", method = RequestMethod.POST)
    @ApiOperation(value = "专车/快车/出租车信息导出", httpMethod = "POST")
    public void export(@RequestBody AdminOrderPageParam orderPageParam, HttpServletResponse response) {
        if (ParamUtil.isIllegal(orderPageParam.getTypeModule())) {
            return;
        }
        // 文件名获取
        int typeModule = orderPageParam.getTypeModule();
        String fileName = "";
        if (typeModule == CommonConstant.BUSINESS_TYPE_TAXI) {
            fileName = "出租车订单.xlsx";
        }
        if (typeModule == CommonConstant.BUSINESS_TYPE_SPEC) {
            fileName = "专车订单.xlsx";
        }
        if (typeModule == CommonConstant.BUSINESS_TYPE_EXPRESS) {
            fileName = "快车订单.xlsx";
        }
        try (OutputStream os = response.getOutputStream()) {
            ResponseData<List<AdminGeneralOrderVo>> responseData = orderAdminService.exportCommon(orderPageParam);
            if (responseData.isSuccess() && CollectionUtils.isNotEmpty(responseData.getData())) {
                List<AdminGeneralOrderVo> result = responseData.getData();
                Workbook workbook = new XSSFWorkbook();
                toExcel(result, workbook);
                response.setHeader("Content-Disposition", "attachment; filename=" + java.net.URLEncoder.encode(fileName, "UTF-8"));
                response.setContentType("application/octet-stream");
                response.setCharacterEncoding("utf-8");
                workbook.write(os);
            }
        } catch (IOException e) {
            log.error("order export error. type:{}", typeModule, e);
        }
    }

    /**
     * 生成excel
     *
     * @param list
     * @throws IOException
     */
    private void toExcel(List<AdminGeneralOrderVo> list, Workbook workbook) throws IOException {
        // 生成excel
        Sheet sheet = workbook.createSheet();
        //宽度5.38
        sheet.setColumnWidth(0, ((5 + 1) * 7 + 5) / 7 * 256);
        //宽度50.38
        sheet.setColumnWidth(1, ((10 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(2, ((25 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(3, ((25 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(4, ((25 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(5, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(6, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(7, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(8, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(9, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(10, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(11, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(12, ((35 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(13, ((35 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(14, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(15, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(16, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(17, ((20 + 1) * 7 + 5) / 7 * 256);
        sheet.setColumnWidth(18, ((20 + 1) * 7 + 5) / 7 * 256);
        //创建第一行
        Row row = sheet.createRow(0);
        row.createCell(0).setCellValue("序号");
        row.createCell(1).setCellValue("类型");
        row.createCell(2).setCellValue("编号");
        row.createCell(3).setCellValue("外部订单号");
        row.createCell(4).setCellValue("用车时间");
        row.createCell(5).setCellValue("下单人");
        row.createCell(6).setCellValue("下单人电话");
        row.createCell(7).setCellValue("乘车人");
        row.createCell(8).setCellValue("乘车人电话");
        row.createCell(9).setCellValue("司机");
        row.createCell(10).setCellValue("司机电话");
        row.createCell(11).setCellValue("车牌");
        row.createCell(12).setCellValue("车型");
        row.createCell(13).setCellValue("出发地");
        row.createCell(14).setCellValue("目的地");
        row.createCell(15).setCellValue("状态");
        row.createCell(16).setCellValue("订单总金额");
        row.createCell(17).setCellValue("订单来源");
        row.createCell(18).setCellValue("异常备注");

        for (int i = 0; i < list.size(); i++) {
            AdminGeneralOrderVo bean = list.get(i);
            Row dateRow = sheet.createRow(i + 1);
            dateRow.createCell(0).setCellValue(i + 1);
            for (int cellNum = 1; cellNum <= MagicConstant.INT_SIXTEEN; cellNum++) {
                Cell cell = dateRow.createCell(cellNum);
                switch (cellNum) {
                    case 1: {
                        String typeTripName = "";
                        switch (bean.getTypeTrip()) {
                            case CommonConstant.NEW_ORDER_TYPE_TRIP_GENERAL:
                                typeTripName = "用车";
                                break;
                            case CommonConstant.NEW_ORDER_TYPE_TRIP_DAILY:
                                typeTripName = "日租";
                                break;
                            case CommonConstant.NEW_ORDER_TYPE_TRIP_HALF:
                                typeTripName = "半日租";
                                break;
                            case CommonConstant.NEW_ORDER_TYPE_TRIP_SEND:
                                typeTripName = "送机";
                                break;
                            case CommonConstant.NEW_ORDER_TYPE_TRIP_MEET:
                                typeTripName = "接机";
                                break;
                            default:
                                break;
                        }
                        cell.setCellValue(typeTripName);
                        break;
                    }
                    case 2: {
                        if (bean.getOrderNo() != null) {
                            cell.setCellValue(bean.getOrderNo());
                        }
                        break;
                    }
                    case 3: {
                        if (bean.getExtOrderId() != null) {
                            cell.setCellValue(bean.getExtOrderId());
                        }
                        break;
                    }
                    case 4: {
                        if (bean.getDeparTime() != null) {
                            cell.setCellValue(DateUtils.format(bean.getDeparTime(), "yyyy-MM-dd HH:mm:ss"));
                        }
                        break;
                    }
                    case 5: {
                        if (bean.getPasNickName() != null) {
                            cell.setCellValue(bean.getPasNickName());
                        }
                        break;
                    }
                    case 6: {
                        cell.setCellValue(bean.getPasMobile());
                        break;
                    }
                    case 7: {
                        if (bean.getActPasNickName() != null) {
                            cell.setCellValue(bean.getActPasNickName());
                        }
                        break;
                    }
                    case 8: {
                        cell.setCellValue(bean.getActPasMobile());
                        break;
                    }
                    case 9: {
                        if (bean.getDriName() != null) {
                            cell.setCellValue(bean.getDriName());
                        }
                        break;
                    }
                    case 10: {
                        if (bean.getDirMobile() != null) {
                            cell.setCellValue(bean.getDirMobile());
                        }
                        break;
                    }
                    case 11: {
                        if (bean.getPlateNum() != null) {
                            cell.setCellValue(bean.getPlateNum());
                        }
                        break;
                    }
                    case 12: {
                        if (bean.getModelName() != null) {
                            cell.setCellValue(bean.getModelName());
                        }
                        break;
                    }
                    case 13: {
                        cell.setCellValue(bean.getOriginAddr());
                        break;
                    }
                    case 14: {
                        if (bean.getDestAddr() != null) {
                            cell.setCellValue(bean.getDestAddr());
                        }
                        break;
                    }
                    case 15: {
                        String mainStatusName = "";
                        switch (bean.getMainStatus()) {
                            case 1:
                                mainStatusName = "新建订单";
                                break;
                            case 2:
                                mainStatusName = "订单进行中";
                                break;
                            case 3:
                                mainStatusName = "行程结束、待支付";
                                break;
                            case 4:
                                mainStatusName = "支付完成、订单结束";
                                break;
                            case 5:
                                mainStatusName = "订单取消（完结）";
                                break;
                            default:
                                break;
                        }
                        cell.setCellValue(mainStatusName);
                        break;
                    }
                    case 16: {
                        if (bean.getTotalFare() != null) {
                            cell.setCellValue(bean.getTotalFare()+"元");
                        }
                        break;
                    }
                    case 17: {
                        String sourceName = "";
                        switch (bean.getSource()) {
                            case OrderConstant.ORDER_SOURCE_APP:
                                sourceName = "APP移动端";
                                break;
                            case OrderConstant.ORDER_SOURCE_WX:
                                sourceName = "微信公众号";
                                break;
                            case OrderConstant.ORDER_SOURCE_PHONE:
                                sourceName = "电话叫车";
                                break;
                            case OrderConstant.ORDER_SOURCE_PC:
                                sourceName = "pc网站";
                                break;
                            case OrderConstant.ORDER_SOURCE_ADMIN:
                                sourceName = "后台下单";
                                break;
                            case OrderConstant.ORDER_SOURCE_EXTERNAL:
                                sourceName = "国铁订单";
                                break;
                            default:
                                break;
                        }
                        cell.setCellValue(sourceName);
                        break;
                    }
                    case 18: {
                        if (bean.getTypeAbnormal() != null) {
                            switch (bean.getTypeAbnormal()) {
                                case 1: {
                                    cell.setCellValue("乘客修改目的地");
                                    break;
                                }
                                case 2: {
                                    cell.setCellValue("费用不认可-司机绕路");
                                    break;
                                }
                                case 3: {
                                    cell.setCellValue("乘客要求变更路线");
                                    break;
                                }
                                case 4: {
                                    cell.setCellValue("乘客中途下车");
                                    break;
                                }
                                case 5: {
                                    cell.setCellValue("车辆故障");
                                    break;
                                }
                                case 6: {
                                    cell.setCellValue("交通事故");
                                    break;
                                }
                                case 7: {
                                    cell.setCellValue("乘客投诉");
                                    break;
                                }
                                case 8: {
                                    cell.setCellValue("费用不认可-司机多收费");
                                    break;
                                }
                                case 9: {
                                    cell.setCellValue("费用不认可-司机额外收费");
                                    break;
                                }
                                case 10: {
                                    cell.setCellValue("异常订单-乘客未上车扣费");
                                    break;
                                }
                                case 11: {
                                    cell.setCellValue("异常订单-司机刷单");
                                    break;
                                }
                                default:
                                    break;
                            }
                        }
                        break;
                    }
                    default:
                        break;
                }
            }

        }
    }

}
